﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Data;

namespace Tracy.CoreLib.Data
{
    public class TracyRelationship : ManagedXmlModel_CommonFunctions , IManagedXmlModelItem 
    {

        #region 构造函数
        public TracyRelationship(int propertyId, int sourceId, string sourceType, int targetId, string targetType) : base() 
        {
            PropertyId = propertyId;
            SourceId = sourceId;
            SourceType = sourceType;
            TargetId = targetId;
            TargetType = targetType;
        }
        public TracyRelationship(string xml) : base(xml) { }
        public TracyRelationship(XmlNode node) : base(node) { }
        #endregion
        #region IXmlModel Members

        public string XmlNodeName
        {
            get { return Constants.CONST_TAG_ITEM; }
        }

        #endregion

        #region IKeyedItem Members

        public string Key
        {
            get { return Id.ToString(); }
        }

        #endregion

        public override void SetValue(string key, string value)
        {
            if (Id == -1)
            {
                switch (key)
                {
                    case Constants.CONST_TAG_PROPERTYID: PropertyId = Convert.ToInt32(value); break;
                    case Constants.CONST_TAG_SOURCEID: SourceId = Convert.ToInt32(value); break;
                    case Constants.CONST_TAG_TARGETID: TargetId = Convert.ToInt32(value); break;
                    default: base.SetValue(key, value); break;
                }
            }
            else
            {
                throw new TracyException(TracyException.EXCEPTION_ID_ALREADY_SET);
            }
        }

        private int _propertyId;
        public int PropertyId
        {
            get
            {
                return _propertyId;
            }
            protected set
            {
                _propertyId = value;
                Data[Constants.CONST_TAG_PROPERTYID] = value.ToString();
            }
        }

        private int _sourceId;
        public int SourceId
        {
            get
            {
                return _sourceId;
            }
            protected set
            {
                _sourceId = value;
                Data[Constants.CONST_TAG_SOURCEID] = value.ToString();
            }
        }

        private int _targetId;
        public int TargetId
        {
            get
            {
                return _targetId;
            }
            protected set
            {
                _targetId = value;
                Data[Constants.CONST_TAG_TARGETID] = value.ToString();
            }
        }

        public string SourceType
        {
            get
            {
                if (Data.ContainsKey(Constants.CONST_TAG_SOURCETYPE)) return Data[Constants.CONST_TAG_SOURCETYPE];
                else return "";
            }
            protected set
            {
                Data[Constants.CONST_TAG_SOURCETYPE] = value;
            }
        }

        public string TargetType
        {
            get
            {
                if (Data.ContainsKey(Constants.CONST_TAG_TARGETTYPE)) return Data[Constants.CONST_TAG_TARGETTYPE];
                else return "";
            }
            protected set
            {
                Data[Constants.CONST_TAG_TARGETTYPE] = value;
            }
        }

        protected override void PreParseXml(XmlNode node)
        {
            try
            {
                PropertyId = Convert.ToInt32(SelectNode(node, Constants.CONST_TAG_PROPERTYID, true).InnerText);
                SourceId = Convert.ToInt32(SelectNode(node, Constants.CONST_TAG_SOURCEID, true).InnerText);
                TargetId = Convert.ToInt32(SelectNode(node, Constants.CONST_TAG_TARGETID, true).InnerText);
            }
            catch (Exception e)
            {
                throw new TracyException(TracyException.EXCEPTION_XML_VALUE_FORMAT, "ID必须是数字。出错位置：\n" + node.InnerXml, e.Message);
            }
        }
    }

    public class TracyRelationshipProvider : XmlModelProvider_CommonFunctions, IXmlModelProvider
    {
        #region 构造函数
        public TracyRelationshipProvider() : base() { }
        public TracyRelationshipProvider(string xml) : base(xml) { }
        public TracyRelationshipProvider(XmlNode node) : base(node) { }
        #endregion

        #region IXmlModelContainer Members


        public IXmlModelItem GenerateChild(XmlNode node)
        {
            return new TracyRelationship(node);
        }

        #endregion

        #region IXmlModel Members

        public string XmlNodeName
        {
            get { return Constants.CONST_TAG_RELATIONSHIP; }
        }

        #endregion

        TracyDataSet.DataTableRelationshipsDataTable _relationshipTable;

        private TracyDataSet.DataTableRelationshipsDataTable RelationshipTable
        {
            get { if (_relationshipTable == null)_relationshipTable = new TracyDataSet.DataTableRelationshipsDataTable(); return _relationshipTable; }
        }

        public override void AddItem(IXmlModelItem newItem)
        {
            base.AddItem(newItem);
            if (newItem is TracyRelationship)
            {
                TracyRelationship newRelationship = (TracyRelationship)newItem;
                RelationshipTable.AddDataTableRelationshipsRow(newRelationship.Id, newRelationship.PropertyId, newRelationship.SourceId, newRelationship.SourceType, newRelationship.TargetId, newRelationship.TargetType);
            }
        }

        public override void RemoveItem(IXmlModelItem oldItem)
        {
            base.RemoveItem(oldItem);
            if (oldItem is TracyRelationship)
            {
                TracyRelationship oldRelationship = (TracyRelationship)oldItem;
                RelationshipTable.RemoveDataTableRelationshipsRow(RelationshipTable.FindByid(oldRelationship.Id));
            }
        }

        public IManagedXmlModelCollection FindByProperty(int propertyid)
        {
            IManagedXmlModelCollection rtn = new ManagedXmlModelCollection();
            DataRow[] rows = RelationshipTable.Select("propertyid=" + propertyid);
            foreach (TracyDataSet.DataTableRelationshipsRow row in rows)
            {
                rtn.Add(Items[row.id]);
            }
            return rtn;
        }

        public IManagedXmlModelCollection FindBySource(int sourceid, string sourcetype)
        {
            IManagedXmlModelCollection rtn = new ManagedXmlModelCollection();
            DataRow[] rows = RelationshipTable.Select("sourceid=" + sourceid + " and sourcetype='" + sourcetype + "'");
            foreach (TracyDataSet.DataTableRelationshipsRow row in rows)
            {
                rtn.Add(Items[row.id]);
            }
            return rtn;
        }

        public IManagedXmlModelCollection FindByTarget(int targetid, string targettype)
        {
            IManagedXmlModelCollection rtn = new ManagedXmlModelCollection();
            DataRow[] rows = RelationshipTable.Select("targetid=" + targetid + " and targettype='" + targettype + "'");
            foreach (TracyDataSet.DataTableRelationshipsRow row in rows)
            {
                rtn.Add(Items[row.id]);
            }
            return rtn;
        }
    }

//    public class XmlModelCollectionDictionary<T>
//    {
//        Dictionary<T, XmlModelCollection> dic = new Dictionary<T, XmlModelCollection>();
//        public XmlModelCollection this[T key]
//        {
//            get 
//            {
//                if (dic.ContainsKey(key))
//                {
//                    return dic[key];
//                }
//                else
//                {
//                    return null;
//                }
//            }
//        }

//        public void AddItem(T key, IXmlModelItem item)
//        {
//            if (this[key] == null)
//            {
//                dic[key] = new XmlModelCollection();
//            }

//            this[key].Add(item);
//        }

//        public void RemoveItem(T key, IXmlModelItem item)
//        {
//            if (this[key] == null) return;
//            if (this[key].Contains(item)) 
//                this[key].Remove(item);
//        }

//        public void RemoveItem(IXmlModelItem item)
//        {
//            foreach (T key in dic.Keys)
//            {
//                RemoveItem(key, item);
//            }
//        }

//        public bool ContainsKey(T key)
//        {
//            return dic.ContainsKey(key);
//        }
//    }
}

